﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using pl.OC.DB;
using System.IO;
using pl.OC;

namespace WorkTimeApplication
{
    public partial class WTAForm : Form
    {
        #region Class members

        private static WTAForm          ms_instance;
        
        private bool                    m_toolTipWasShown;
        private delegate void           UpdateStatusBarDelegate(String Caption, bool UseProgressBar);

        #endregion

        public static WTAForm GetInstance()
        {
            return ms_instance;
        }

        public WTAForm()
        {
            InitializeComponent();
            ms_instance = this;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            workTimePanelOverall.DB                 = DBHandler.getInstance();
            workTimePanelDaily.DB                   = DBHandler.getInstance();
            workTimePanelWeekly.DB                  = DBHandler.getInstance();
            workTimePanelMonthly.DB                 = DBHandler.getInstance();

            DBHandler.getInstance().TimeInterval    = Properties.Settings.Default.RefreshDBInSeconds * 1000;
            DBHandler.getInstance().DBFile          = new FileInfo(Properties.Settings.Default.DBDirectory + "/" + Properties.Settings.Default.DBFileName);
            DBHandler.getInstance().OnEntryUpdated  += new DBHandler.DBEntryUpdated(Form1_OnEntryUpdated);

            DBHandler.getInstance().OnStartWorking  += new DBHandler.StartWorkingDelegate(Form1_OnStartWorking);
            DBHandler.getInstance().OnEndWorking    += new DBHandler.EndWorkingDelegate(Form1_OnEndWorking);

            DBHandler.getInstance().Start();

            workTimePanelOverall.ZedGraph.PrintDocument.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(PrintDocument_PrintPage);

            UpdateContectMenuNotifyIconState();

            UpdateStatusBar("IDLE", false);
        }

        void Form1_OnEndWorking()
        {
            UpdateStatusBar("IDLE", false);
        }

        void Form1_OnStartWorking()
        {
            UpdateStatusBar("DB Working", true);
        }

        void Form1_OnEntryUpdated(FileInfo dbFile, pl.OC.Entity.WorkSheet worksheet, pl.OC.Entity.WorkEntryComplexType entry, TimeSpan dt)
        {
            TimeSpan ts = new TimeSpan();

            foreach (pl.OC.Entity.WorkEntryComplexType wect in worksheet.WorkEntry)
            {
                DateTime start = wect.startTime;
                if (start.Date == DateTime.Now.Date)
                {
                    ts += (wect.endTime - start);
                }
            }

            StringBuilder sb = new StringBuilder();
            sb.Append("Worked: ");
            sb.Append(ts.Hours).Append(":").Append(ts.Minutes);
            sb.Append("/").Append(worksheet.OvertimeThreshold).Append(":00");

            notifyIcon1.Text = sb.ToString();

            if (!m_toolTipWasShown && ts.TotalHours > worksheet.OvertimeThreshold)
            {
                notifyIcon1.BalloonTipText  = "It is safe to go home now";
                m_toolTipWasShown           = true;
                notifyIcon1.ShowBalloonTip(5000);
            }

            if (Properties.Settings.Default.OvertimeThreshold != worksheet.OvertimeThreshold)
            {
                worksheet.OvertimeThreshold = (int)Properties.Settings.Default.OvertimeThreshold;
            }
        }

        private void notifyIcon1_DoubleClick(object sender, EventArgs e)
        {
            Show();
            this.WindowState = FormWindowState.Normal;
            UpdateContectMenuNotifyIconState();
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                Hide();
                UpdateContectMenuNotifyIconState();
            }
        }

        private void asNormalBackupToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                FileInfo fi = DBHandler.getInstance().CreateBackup();
                MessageBox.Show("Backup file: " + fi.Name + " created", "Backup created");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Unable to create backup: " + ex.Message, "Error while creating backup");
            }
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (new AboutForm()).Show();
        }

        private void showMainPanelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Show();
            this.WindowState = FormWindowState.Normal;
            UpdateContectMenuNotifyIconState();
        }

        private void propertiesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (new ConfigurationForm()).Show();
        }

        private void asFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "ZIP (*.gzip)|*.gzip";

            if (sfd.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    FileInfo fi = DBHandler.getInstance().CreateBackup(new FileInfo(sfd.FileName));
                    MessageBox.Show("Backup file: " + fi.Name + " created", "Backup created");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Unable to create backup: " + ex.Message, "Error while creating backup");
                }
            }
        }

        private void fromFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd      = new OpenFileDialog();
            ofd.Filter              = "GZIP (*.gzip)|*.gzip";
            ofd.CheckFileExists     = true;

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    FileInfo dst = DBHandler.getInstance().ReadFromBackup(new FileInfo(ofd.FileName), null);
                    DialogResult dr = MessageBox.Show("Change DB to extracted file?", "Change DB", MessageBoxButtons.YesNo);

                    switch (dr)
                    {
                        case DialogResult.Yes:
                        {
                            Properties.Settings.Default.DBDirectory = dst.DirectoryName;
                            Properties.Settings.Default.DBFileName = dst.Name;
                            Properties.Settings.Default.Save();
                            DBHandler.getInstance().DBFile = dst;
                            MessageBox.Show("New DB file opened", "Info");
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Unable to read backup file: " + ex.Message, "Error while creating backup");
                }
            }
        }

        protected void UpdateContectMenuNotifyIconState()
        {
            contextMenuStripNotifyIcon.Enabled = this.WindowState == FormWindowState.Minimized;
            contextMenuStripNotifyIcon.Invalidate();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            Graphics g = e.Graphics;

            Font font           = new Font("Arial", 10);
            float lineHeight    = font.GetHeight(e.Graphics);
            float x             = e.MarginBounds.Left;
            float y             = e.MarginBounds.Top;
            e.Graphics.DrawString("Autogenerated page by " + Application.ProductName, font, Brushes.Black, x, e.MarginBounds.Bottom);
            TimeSpan ts         = new TimeSpan();

            
            DataTable dt = new DataTable("COS");
            

            DataGridView dataGridView1 = new DataGridView();
            BindingList<pl.OC.Entity.WorkEntryComplexType> bindingList = new BindingList<pl.OC.Entity.WorkEntryComplexType>(DBHandler.getInstance().Worksheet.WorkEntry);
            List<pl.OC.Entity.WorkEntryComplexType> list = new List<pl.OC.Entity.WorkEntryComplexType>();
            list.AddRange(DBHandler.getInstance().Worksheet.WorkEntry);

            dataGridView1.AutoGenerateColumns = true;
            dataGridView1.Columns.Add("StartTime", "StartTime");
            dataGridView1.Columns.Add("EndTime", "EndTime");

            dataGridView1.DataSource = DBHandler.getInstance().Worksheet.WorkEntry;

            foreach (pl.OC.Entity.WorkEntryComplexType wect in DBHandler.getInstance().Worksheet.WorkEntry)
            {
                dataGridView1.Rows.Add(wect.startTime, wect.endTime);                
            }

            
            Bitmap bm = new Bitmap(dataGridView1.Width, dataGridView1.Height);
            dataGridView1.DrawToBitmap(bm, new Rectangle(0, 0, dataGridView1.Width, dataGridView1.Height));
            e.Graphics.DrawImage(bm, 0, 0);




            

            /*
            

            foreach (pl.OC.Entity.WorkEntryComplexType wect in DBHandler.getInstance().Worksheet.WorkEntry)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("Started: " + wect.startTime);
                sb.Append(" Ended: " + wect.endTime);

                TimeSpan diff = (DateTime.Parse(wect.endTime) - DateTime.Parse(wect.startTime));

                sb.Append(" Worked: " + (int)diff.TotalHours + ":" + diff.Minutes);
                ts += diff;
                sb.Append(" SUM: " + (int)ts.TotalHours + ":" + ts.Minutes);

                e.Graphics.DrawString(sb.ToString(), font, Brushes.Black, x, y);

                y += lineHeight;
            }
            */
        }

        private void PrintDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            Graphics g = e.Graphics;

            Font font = new Font("Arial", 10);
            float lineHeight = font.GetHeight(e.Graphics);
            float x = e.MarginBounds.Left;
            float y = e.MarginBounds.Top;
            e.Graphics.DrawString("Autogenerated page by " + Application.ProductName, font, Brushes.Black, x, e.MarginBounds.Bottom);
        }

        private void printToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            PrintDialog pd = new PrintDialog();
            if (pd.ShowDialog() == DialogResult.OK)
            {
                MultiPrintDocument mpd = new MultiPrintDocument(printDocument1, workTimePanelOverall.ZedGraph.PrintDocument);
                mpd.Print();
            }
        }

        private void previewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            PrintPreviewDialog ppd = new PrintPreviewDialog();
            MultiPrintDocument mpd = new MultiPrintDocument(printDocument1, workTimePanelOverall.ZedGraph.PrintDocument);
            ppd.Document = mpd;
            ppd.ShowDialog();
        }

        public void UpdateStatusBar(String caption, bool ProgressBarStatus)
        {
            BeginInvoke(new UpdateStatusBarDelegate(this.UpdateStatusBarInternal), new object []{caption, ProgressBarStatus});
        }

        private void UpdateStatusBarInternal(String Caption, bool UseProgressBar)
        {
            toolStripProgressBar1.Enabled   = UseProgressBar;
            toolStripProgressBar1.Style     = toolStripProgressBar1.Enabled ? ProgressBarStyle.Marquee : ProgressBarStyle.Blocks;
            toolStripStatusLabel1.Text      = Caption;
        }

        private void backupAndCreateNewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "ZIP (*.gzip)|*.gzip";

            if (sfd.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    FileInfo fi = DBHandler.getInstance().CreateBackup(new FileInfo(sfd.FileName));
                    MessageBox.Show("Backup file: " + fi.Name + " created", "Backup created");
                    DBHandler.getInstance().ClearDB();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Unable to create backup: " + ex.Message, "Error while creating backup");
                }
            }
        }
    }
}
